package com.clinbrain;

import com.facebook.presto.spi.function.Description;
import com.facebook.presto.spi.function.ScalarFunction;
import com.facebook.presto.spi.function.SqlNullable;
import com.facebook.presto.spi.function.SqlType;
import com.facebook.presto.spi.type.StandardTypes;
import io.airlift.slice.Slice;
import io.airlift.slice.Slices;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.UNICODE_CHARACTER_CLASS;

/**
 * @ClassName CdaXmlParseStr
 * @Description TODO
 * @Author p
 * @Date 2020/3/17 10:52
 * @Version 1.0
 **/

public final class CdaXmlParseStr {

    private final static Pattern CHINESE_PATTERN = Pattern.compile("[\\u4e00-\\u9fa5]", UNICODE_CHARACTER_CLASS);

    private CdaXmlParseStr() {

    }

    @ScalarFunction("cda_xml_parse_str")
    @Description("get chinese from xml. first param: xml content, second param: find xml attribute, third param: get from value")
    @SqlType(StandardTypes.VARCHAR)
    @SqlNullable
    public static Slice cda_xml_parse_str(@SqlType(StandardTypes.VARCHAR) Slice xmlStr,
                                          @SqlType(StandardTypes.BOOLEAN) boolean findAttribute,
                                          @SqlType(StandardTypes.BOOLEAN) boolean isGetValue) {
        if (null == xmlStr) {
            return null;
        }

        //去除xml中的单引号
        String xmlContent = xmlStr.toStringUtf8().replaceAll("'", "");
        try {
            List<String> chineseList = parseXml(xmlContent, findAttribute, isGetValue);
            if (null == chineseList || chineseList.isEmpty()) {
                return null;
            }

            StringBuilder stringBuilder = new StringBuilder();
            for (String chinese: chineseList) {
                stringBuilder.append(chinese);
                stringBuilder.append(",");
            }
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
            return Slices.utf8Slice(stringBuilder.toString());
        } catch (Exception e) {
            return null;
        }
    }

    private static List<String> parseXml(String xmlContent, boolean findAttribute, boolean isGetValue) {
        List<String> chineseList = new LinkedList<>();
        try {
            Document document = DocumentHelper.parseText(xmlContent);
            getNodes(document.getRootElement(), chineseList, findAttribute, isGetValue);
        } catch (DocumentException e) {
            return null;
        }

        return chineseList;
    }

    private static void getNodes(Element node, List<String> chineseList, boolean findAttribute, boolean isGetValue) {
        //当前节点所有属性的list
        List<Attribute> attributes = node.attributes();
        //遍历当前节点的所有属性,findAttribute为true是匹配属性中文值
        if (findAttribute) {
            for (Attribute attribute : attributes) {
                Matcher matcher = CHINESE_PATTERN.matcher(attribute.getValue());
                if (matcher.find()) {
                    chineseList.add(attribute.getValue().replaceAll("&nbsp;", "")
                            .replaceAll("&KeyEnter;", ""));
                }
            }
        }

        if (isGetValue) {
            if ("Value".equals(node.getName())) {
                chineseList.add(node.getTextTrim().replaceAll("&nbsp;", "")
                        .replaceAll("&KeyEnter;", ""));
            }
        } else {
            Matcher matcher = CHINESE_PATTERN.matcher(node.getTextTrim());
            if (matcher.find()) {
                chineseList.add(node.getTextTrim().replaceAll("&nbsp;", "")
                        .replaceAll("&KeyEnter;", ""));
            }
        }

        //递归遍历当前节点所有的子节点,所有一级子节点的list
        List<Element> elements = node.elements();
        //遍历所有一级子节点
        for (Element e : elements) {
            //递归
            getNodes(e, chineseList, findAttribute, isGetValue);
        }
    }

    public static void main(String[] args) throws Exception {
        String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<bookstore>\n" +
                "    <book id=\"第一1\">\n" +
                "        <name>冰与火之歌1。歌。</name>\n" +
                "        <author>乔治马丁</author>\n" +
                "        <year>2014</year>\n" +
                "        <price>89</price>\n" +
                "    </book>\n" +
                "    <book id=\"2\">\n" +
                "        <value>安徒生童话</value>\n" +
                "        <year>2004</year>\n" +
                "        <price>77</price>\n" +
                "        <language>English</language>\n" +
                "    </book>    \n" +
                "</bookstore>";

        Slice result = cda_xml_parse_str(Slices.utf8Slice(xmlStr), false, true);
        if (null != result) {
            System.out.println(result.toStringUtf8());
        } else {
            System.out.println("not xml.");
        }

    }
}
